const operator = ['+', '-', '*', '÷']
let operatorType = operator
let range
exports.main = async (event, context) => {
  let type = parseInt(event.type) || 1
  range = parseInt(event.range) || 10
  num = parseInt(event.num) || 20
  // 加减法
  if (type == 1) {
    operatorType = ['+', '-']
  } else if (type == 2) {
    // 乘法
    operatorType = ['*']
  }
  return createExpression(num)
}
// 随机操作符优先级
function operatorRank(operatorOne, operatorTwo) {
  if (operatorOne === void 0) {
    throw new Error('you not have a expression')
  }
  if (operatorTwo === undefined) {
    return true
  }
  if (operatorOne === '/' || operatorOne === '*') {
    return !(operatorTwo === '/' || operatorTwo === '*')
  } else if (operatorOne === '+' || operatorOne === '-') {
    return operatorTwo === ')' || operatorTwo === '('
  } else if (operatorTwo === ')' || operatorTwo === '(') {
    return false
  }
}

function changeFormat(array) {
  let freeback = array.slice(0)
  for (let i = 0; i < array.length; i++) {
    if (array[i] === '÷') {
      freeback[i] = '/'
    }
    if (array[i].length > 1 && array[i].indexOf('/') !== -1) {
      if (array[i].indexOf('^') !== -1) {
        let temp = freeback[i].split('/')
        let one = temp[0].split('^')
        freeback[i] = Number(one[0]) + Number(one[1] / temp[1])
      } else {
        let temp = freeback[i].split('/')
        freeback[i] = temp[0] / temp[1]
      }
    }
  }
  return freeback
}

function counter(expressionArray) {
  expressionArray = changeFormat(expressionArray.split(' '))
  let outStack = []
  let operatorStack = []
  for (let i = 0; i < expressionArray.length; i++) {
    if (typeof Number(expressionArray[i]) === 'number' && !isNaN(Number(expressionArray[i]))) {
      outStack.push(expressionArray[i])
    } else if (expressionArray[i] === '(') {
      operatorStack.push(expressionArray[i])
    } else if (
      expressionArray[i] === '+' ||
      expressionArray[i] === '-' ||
      expressionArray[i] === '*' ||
      expressionArray[i] === '/'
    ) {
      if (operatorRank(expressionArray[i], operatorStack[operatorStack.length - 1])) {
        operatorStack.push(expressionArray[i])
      } else {
        outStack.push(operatorStack.pop())
        while (!operatorRank(expressionArray[i], operatorStack[operatorStack.length - 1])) {
          outStack.push(operatorStack.pop())
        }
        operatorStack.push(expressionArray[i])
      }
    } else if (expressionArray[i] === ')') {
      while (operatorStack[operatorStack.length - 1] !== '(') {
        outStack.push(operatorStack.pop())
      }
      if (operatorStack[operatorStack.length - 1] === '(') {
        operatorStack.pop()
      }
    }
    if (i === expressionArray.length - 1) {
      while (operatorStack.length !== 0) {
        outStack.push(operatorStack.pop())
      }
    }
  }
  return outStack
}

function getResult(suffix) {
  suffix = counter(suffix)
  let resultStack = []
  for (let i = 0; i < suffix.length; i++) {
    if (typeof Number(suffix[i]) === 'number' && !isNaN(Number(suffix[i]))) {
      resultStack.push(Number(suffix[i]))
    } else {
      switch (suffix[i]) {
        case '+': {
          resultStack.push(Number(resultStack.pop()) + Number(resultStack.pop()))
          break
        }
        case '-': {
          let reduce = Number(resultStack.pop())
          let beReduce = Number(resultStack.pop())
          resultStack.push(beReduce - reduce)
          break
        }
        case '*': {
          resultStack.push(Number(resultStack.pop()) * Number(resultStack.pop()))
          break
        }
        case '/': {
          let reduce = Number(resultStack.pop())
          let beReduce = Number(resultStack.pop())
          resultStack.push(beReduce / reduce)
          break
        }
        default: {
          throw new Error('illegal symbol ')
        }
      }
    }
  }
  return resultStack[0]
}
// 获取运算符
function getOperator() {
  return operatorType[Math.floor(Math.random() * operatorType.length)]
}
// 返回非负表达式结果
function _positive(expression) {
  return getResult(expression) >= 0
}
function getRandom() {
  return Math.floor(Math.random() * (range - 1) + 1)
}
function _isNumber(number) {
  return !(typeof number !== 'number' || number < 0)
}
// 生成计算表达式
function createExpression(number, type) {
  if (!_isNumber(number)) {
    throw new Error(`The ${number} is not a number type, please check again!`)
  }
  let result = []
  let operands = null
  let output = ''
  let index = 0
  while (index !== number) {
    operands = Math.floor(Math.random() * (operatorType.length - 1) + 1)
    switch (operands) {
      case 1: {
        output = `${getRandom()} ${getOperator()} ${getRandom()}`
        if (_positive(output)) {
          result.push(`${output} = `)
          index++
        }
        break
      }
      case 2: {
        output = `${getRandom()} ${getOperator()} ${getRandom()}`
        if (_positive(output)) {
          result.push(`${output} = `)
          index++
        }
        break
      }
      case 3: {
        output = `${getRandom()} ${getOperator()} ${getRandom()} ${getOperator()} ${getRandom()}`
        if (_positive(output)) {
          result.push(`${output} = `)
          index++
        }
        break
      }
      default: {
        throw new Error('operands is not in the range')
      }
    }
  }
  return result
}
